/*
 * Copyright (C) 2008 Apple Computer, Inc.  All rights reserved.
 * Copyright (C) 2012 Sony Computer Entertainment Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef WebViewPrivate_h
#define WebViewPrivate_h

#include "PopupMenuClient.h"
#include "RenderBox.h"
#include "RunLoop.h"
#include "WebViewPopupMenu.h"
#include <webkit/WebView.h>
#include <wtf/text/CString.h>
#if USE(ACCELERATED_COMPOSITING)
#include "AcceleratedCompositingContext.h"
#endif

// Match Safari's min/max zoom sizes by default
#define MinimumTextSizeMultiplier       0.5f
#define MaximumTextSizeMultiplier       3.0f
#define TextSizeMultiplierRatio         1.2f

#if OS(PSP2)
#define USE_TILED_BUFFER 1
#else
#define USE_TILED_BUFFER 0
#endif

#if USE_TILED_BUFFER
#include "TiledBufferPainter.h"
#include <cairo.h>
#endif

namespace WebCore {
class ChromeClientManx;
class EditorClientManx;
class FrameLoaderClientManx;
class GeolocationClientManx;
class InspectorClientManx;
class Page;
};

namespace WebKit {

class WebViewPrivate;
class AcceleratedCompositingContext;

class SettingsImpl : public WebSettings {
public:
    SettingsImpl(WebViewPrivate&);
    virtual void setScriptEnabled(bool);
    virtual void setCookieEnabled(bool);
    virtual void setWebGLEnabled(bool);
    virtual void setWebSecurityEnabled(bool);
    virtual void setDeveloperExtrasEnabled(bool);

    WebCore::Settings& settings();

    WebViewPrivate& m_webView;
};

class WebViewPrivate : public WebKit::WebView {
public:
    WebViewPrivate(WebViewClient&);
    virtual ~WebViewPrivate();

    void create(WebViewCreateParam&);
    void drawRect(float x, float y, float w, float h, void* data, unsigned dataSize);
    void setClipRect(int x, int y, int w, int h, bool pending);
    void getClipRect(int* x, int* y, int* w, int* h);
    void sendMouseEvent(MouseEventType, MouseButtonType, int x, int y);
    bool sendKeyEvent(Manx::KeyboardEvent&, KeyDefaultBehavior);
    bool sendTouchEvent(const Manx::TouchEvent*);
    void sendGestureEvent(unsigned type, int x, int y);
    void loadURL(const char *url);
    void loadHTML(const char *html, const char *baseUrl);
    void loadData(const char *data, unsigned long dataLen, const char *mimetype, const char *encoding, const char *baseUrl);
    void loadArchive(const char *buf, unsigned long bufLen, const char *url);
    void applyClipRect();
    bool updateClipRect(int x, int y, int w, int h, bool pending);
    void setUserAgent(const char*);
    const char* userAgent();
    void overflowScroll(int, int);
    void reload();
    void stop();
    void goBack();
    void goForward();
    void increaseTextSize();
    void decreaseTextSize();
    void resetTextSize();
    void setComposition(const char *compositionString, unsigned underlineFrom, unsigned underlineTo);
    void cancelComposition();
    void confirmComposition(const char *compositionText, unsigned caretIndex);
    void exitComposition();
    void clearText();
    void setValueToFocusedNode(const String&);
    void hitTest(Manx::Point& hitPoint, WebViewHitTestResult&, bool& elementForm);
    void imageBuffer();
    void setUploadFile(const char* path, const char* name);
    void setSelectedItemsPopupMenu(int index, bool isEnd);
    void getItemPopupMenu(int index);
    void releaseTiles();
    void setDefaultLayoutWidth(int);
    bool getImageInfoHit(WebString& url, const char*& data, unsigned& size);
    void setJavaScriptObj(WebViewJavaScriptObject* o) { m_windowObj = adoptPtr<WebViewJavaScriptObject>(o); }
    WebSettings& settings() { return m_settings; };
    void getInputMethodInfo(InputMethodInfo&);
    void setCaretVisible(bool);
    bool isProcessingUserGesture();
    void setGeolocationPermission(const char* origin, bool isAllowed);
    void updateGeolocationPosition(const WebViewGeolocationPosition*);

private:
    friend WebCore::Page* corePage(WebView*);
    friend class WebCore::ChromeClientManx;
    friend class WebCore::EditorClientManx;
    friend class WebCore::FrameLoaderClientManx;
    friend class WebCore::GeolocationClientManx;
    friend class WebCore::InspectorClientManx;
    friend class ::WebViewPopupMenu;
    friend class SettingsImpl;
#if USE(ACCELERATED_COMPOSITING)
    friend class AcceleratedCompositingContext;
#endif

    void destroy();
    void loadArchiveWithSharedBuffer(WTF::RefPtr<WebCore::SharedBuffer>, WebCore::KURL baseKURL);
    bool canGoBack();
    bool canGoForward();
    bool canIncreaseTextSize() const;
    bool canDecreaseTextSize() const;
    void confirmComposition();
    void initSettings();
    void invalidate(const WebCore::IntRect& updateRect, bool immediate);
    bool doOverflowScroll();
    bool isNeedOverflowScroll();
    void resetOverflowScroll(int* previousDeltaX = 0, int* previousDeltaY = 0);
    void didCommitLoad();
    void scheduleDisplay(double delay = 0);
    void displayTimerFired();
    void focusInputText();

    WebViewJavaScriptObject* javaScriptObj() const { return m_windowObj.get(); }
    WebViewClient& client() const { return m_client; }

    void loadJavaScriptURL(const WebCore::KURL&);

    OwnPtr<WebCore::GeolocationClientManx> m_geolocationClient;

    WebViewClient& m_client;

    SettingsImpl m_settings;
    WebViewPopupMenu *m_popupMenu;

    WebCore::Frame *m_frame;
    OwnPtr<WebCore::Page> m_page;

    int m_defaultLayoutWidth;
    WebCore::IntSize m_viewSize;

    WebCore::ViewportAttributes m_viewportAttr;

    int m_textureWidth, m_textureHeight;
#if !USE_TILED_BUFFER
    int m_textureStride;
    int m_textureBufferSize;
    unsigned char *m_textureBuffer;

    cairo_t *m_cairoContext;
    cairo_surface_t *m_cairoSurface;
#endif

    float m_textMagnifier;

    int m_contentsWidth;
    int m_contentsHeight;

    CString m_userAgent;

    WebCore::RunLoop::Timer<WebViewPrivate> m_displayTimer;
#if USE_TILED_BUFFER
    tilebackend::PoolInterface* m_pool;
    tilebackend::PainterInterface* m_painter;
    WebCore::TiledBufferPainter* m_tiledBufferPainter;
#endif

    WTF::Mutex m_mutex;
    WTF::Mutex m_overflowScrollMutex;

    bool m_canScroll;
    int m_overflowScrollDeltaX;
    int m_overflowScrollDeltaY;
    WebCore::Node* m_overflowScrollTarget;

    int m_clipX;
    int m_clipY;
    int m_clipW;
    int m_clipH;
    bool m_pending;
    bool m_updatedClipRect;

    WebCore::KURL m_imageKURL;
    RefPtr<WebCore::Image> m_imageRef;

    OwnPtr<WebViewJavaScriptObject> m_windowObj;

#if USE(ACCELERATED_COMPOSITING)
    OwnPtr<WebKit::AcceleratedCompositingContext> m_acceleratedCompositingContext;
#endif
};

WebCore::Page* corePage(WebView*);

} // namespace WebKit

#endif // WebViewPrivate_h
